<template>
  <teleport to="body">
    <div class="setup-mark" v-if="showMark">
      <div class="setup-mark-box">
        <transition name="fade">
          <div ref="setup" class="setup" v-show="showContent">
            <div class="setup-title">
              <span>设置</span>
              <SvgIcon
                popper-class="setup-close"
                icon-class="close"
                @click="emits('update:show', false)"
              />
            </div>
            <div class="setup-main">
              <el-tabs
                v-model="activeName"
                tab-position="left"
                :before-leave="beforeLeave"
              >
                <el-tab-pane label="账号管理" name="账号管理">
                  <account-manage></account-manage>
                </el-tab-pane>
                <el-tab-pane label="密码管理" name="密码管理">
                  <pass-manage ref="passManageRef"></pass-manage>
                </el-tab-pane>
                <el-tab-pane label="头像管理" name="头像管理"
                  ><avatar-manage></avatar-manage
                ></el-tab-pane>
                <el-tab-pane label="个性签名" name="个性签名"
                  ><signature ref="signatureRef"></signature
                ></el-tab-pane>
                <el-tab-pane label="个人信息" name="个人信息">
                  <info-manage ref="infoManageRef" v-model="infoActiveName"></info-manage>
                </el-tab-pane>
              </el-tabs>
            </div>
          </div>
        </transition>
      </div>
    </div>
  </teleport>
</template>

<script lang="ts" setup>
import { nextTick, ref, watch, onBeforeUnmount, onMounted } from "vue";
import accountManage from "./accountManage.vue";
import passManage from "./passManage.vue";
import avatarManage from "./avatarManage.vue";
import infoManage from "./userInfoManage.vue";
import signature from "./signature.vue";
import { getScrollWid } from "@/plugins/getScrollWid";
import type { TabPanelName } from "element-plus";

const props = withDefaults(
  defineProps<{
    show?: boolean;
    // 父元素
    fatherEle: HTMLLinkElement | undefined;
  }>(),
  {
    show: false,
  }
);
const emits = defineEmits<{
  (e: "update:show", show: boolean): void;
}>();

/**
 * 当前标签页的名称name
 */
const activeName = ref<string>("账号管理");

/**
 * 给密码管理组件一个ref属性
 */
const passManageRef = ref<typeof passManage>();
/**
 * 给个性签名组件一个ref属性
 */
const signatureRef = ref<typeof signature>();
/**
 * 给个人信息组件一个ref属性
 */
const infoManageRef = ref<typeof infoManage>();
/**
 * 切换标签时触发的函数
 */
const beforeLeave = (newName: TabPanelName, oldName: TabPanelName) => {
  if (oldName === "密码管理")
    nextTick(() =>
      // 切换该组件前清除该组件里面的表单数据
      (passManageRef.value as any).resetFields()
    );
  if (newName === "密码管理")
    // 旧密码输入框聚焦
    (passManageRef.value as any).$refs.oldPassRef.focus();
  else if (newName === "个性签名") {
    // 更新个性签名组件的输入框的值
    signatureRef.value?.updateSignature();
    // 个性签名输入框聚焦
    signatureRef.value?.$refs.signatureRef.focus();
  } else if (newName === "个人信息") {
    setTimeout(() => {
      // 更新个人信息组件的昵称输入框的值
      infoManageRef.value?.updateNickName();
      // 个人信息组件的昵称输入框聚焦
      (infoManageRef.value?.$refs.nickNameRef as HTMLInputElement).focus();
    }, 0);
  }
};

// 给中心内容元素一个ref属性
let setup = ref<HTMLDivElement>();
/**
 * 更新内容的位置
 */
const updateContentDirect = () => {
  const rect = props.fatherEle?.getBoundingClientRect()!;
  // 获取浏览器的可视宽度
  const wid: number =
    globalThis.innerWidth ||
    document.body.clientWidth ||
    document.documentElement.clientWidth;
  const fatherEleRight: number = wid - rect.x;
  const fatherTop: number = rect.y;
  // 父元素的高度
  const fatherHei: number = props.fatherEle?.offsetHeight!;
  nextTick(() => {
    setup.value!.style.cssText += `right: ${fatherEleRight - 60}px;top: ${
      fatherTop + scrollY + fatherHei
    }px`;
  });
};

/**
 * 浏览器的可视高度改变则组件的根元素的高度也随之改变
 */
const handleToWid: () => void = (): void => {
  // 获取浏览器的可视高度
  const hei: number =
    globalThis.innerHeight ||
    document.body.clientHeight ||
    document.documentElement.clientHeight;
  // 获取浏览器的可视宽度
  const wid: number =
    globalThis.innerWidth ||
    document.body.clientWidth ||
    document.documentElement.clientWidth;
  if ((document.body.scrollHeight > hei || document.body.scrollWidth > wid) && props.show)
    document.body.style.cssText += `overflow: hidden;padding-right: ${getScrollWid()}px`;
  else if (
    (document.body.scrollHeight <= hei || document.body.scrollWidth <= wid) &&
    props.show
  )
    document.body.style.cssText = "";
  updateContentDirect();
};

/**
 * 是否显示模态框
 */
const showMark = ref<boolean>(false);
/**
 * 是否显示内容
 */
const showContent = ref<boolean>(false);

/**
 * 个人信息标签组件的当前activeName值
 */
const infoActiveName = ref<string>("nickName");

watch(
  () => props.show,
  (show: boolean) => {
    if (show) {
      // 给浏览器添加监听窗口大小变化的事件
      window.addEventListener("resize", handleToWid);
      showMark.value = true;
      nextTick(() => {
        showContent.value = show;
        handleToWid();
      });
      if (activeName.value !== "账号管理") activeName.value = "账号管理";
    } else {
      if (infoActiveName.value !== "nickName") infoActiveName.value = "nickName";
      window.removeEventListener("resize", handleToWid);
      document.body.style.cssText = "";
      showContent.value = false;
      setTimeout(() => (showMark.value = false), 300);
    }
  }
);

onMounted(() => {
  if (props.show) {
    showMark.value = true;
    window.addEventListener("resize", handleToWid);
    setTimeout(() => {
      showContent.value = true;
      handleToWid();
    }, 0);
  }
});

onBeforeUnmount(() => window.removeEventListener("resize", handleToWid));
</script>

<style lang="scss" scoped>
.fade {
  @include fade(0.2s, ease-in-out);
}
.setup {
  position: absolute;
  background-color: rgb(248, 248, 248) !important;
  @include card(500px, 400px, 8px);
  box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
  padding: 0;

  &-mark {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 100;
    overflow: auto;

    &-box {
      @include setWidHei(100%, 100%);
      min-height: 550px;
      min-width: 600px;
    }
  }

  &-title {
    position: relative;
    padding: 6px 10px;

    span {
      font-size: 10px;
      color: $dimFontCor;
    }
  }

  &-close {
    position: absolute;
    top: 8px;
    right: 8px;
    cursor: pointer;
    color: $closeIconColor;

    &:hover {
      color: #000;
    }
  }

  &-main {
    padding: 15px 0 20px;
  }
}
</style>
